home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-01-19 | 69.0 KB | 1,882 lines |
-
-
- DOCUMENTATION FOR NEWMAT08, A MATRIX LIBRARY IN C++
-
- Copyright (C) 1991,2,3,4,5: R B Davies
-
- This is the "how to use" documentation for newmat. Background information on
- the structure of the library is given in newmatb.txt and information about the
- test program is in newmatc.txt.
-
- This document is available as an ascii file, newmata.txt, and in hypertext
- format for reading with "Mosaic". Cross-references in the ascii version are
- given as section numbers.
-
-
- Introduction 1
- Getting started 2
- Reference manual 3
- Error messages 4
- Bugs 5
- Files in newmat08 6
- Problem report form 7
-
-
- 1 Introduction
- = ============
-
- Conditions of use 1.1
- Description 1.2
- Is this the library for you? 1.3
- Other matrix libraries 1.4
- Where to find this library 1.5
- How to contact the author 1.6
- Change history 1.7
- References 1.8
-
-
- 1.1 Conditions of use
- === ========== == ===
-
- Copyright (C) 1991,2,3,4,5: R B Davies.
-
- Permission is granted to use and distribute but not to sell except for costs
- of distribution. Distribution as part of low cost CD-ROM collections is
- welcomed.
- ------------------------------------------------------------------------------
- Please understand that there may still be bugs and errors. Use at your own
- risk. I take no responsibility for any errors or omissions in this package or
- for any misfortune that may befall you or others as a result of its use.
- ------------------------------------------------------------------------------
-
- Please report bugs to me at
-
- robert.davies@vuw.ac.nz
-
- or
-
- Compuserve 72777,656
-
- When reporting a bug please tell me which C++ compiler you are using (if
- known), and what version. Also give me details of your computer (if known).
- Tell me where you downloaded your version of my package from and its version
- number (eg newmat03 or newmat04). (There may be very minor differences between
- versions at different sites). Note any changes you have made to my code. If at
- all possible give me a piece of code illustrating the bug. See the problem
- report form [7].
-
- "Please do report bugs to me."
-
-
-
- 1.2 General description
- === ======= ===========
-
- The package is intended for scientists and engineers who need to manipulate a
- variety of types of matrices using standard matrix operations. Emphasis is on
- the kind of operations needed in statistical calculations such as least
- squares, linear equation solve and eigenvalues.
-
- It supports matrix types
-
- Matrix (rectangular matrix)
- nricMatrix (variant of rectangular matrix)
- UpperTriangularMatrix
- LowerTriangularMatrix
- DiagonalMatrix
- SymmetricMatrix
- BandMatrix
- UpperBandMatrix (upper triangular band matrix)
- LowerBandMatrix (lower triangular band matrix)
- SymmetricBandMatrix
- RowVector (derived from Matrix)
- ColumnVector (derived from Matrix).
-
- Only one element type (float or double) is supported.
-
- The package includes the operations *, +, -, concatenation, inverse,
- transpose, conversion between types, submatrix, determinant, Cholesky
- decomposition, QR triangularisation, singular value decomposition, eigenvalues
- of a symmetric matrix, sorting, fast Fourier transform, printing and an
- interface with "Numerical Recipes in C".
-
- It is intended for matrices in the range 15 x 15 to the maximum size your
- machine will accomodate in a single array. For example 90 x 90 (125 x 125 for
- triangular matrices) in machines that have 8192 doubles as the maximum size of
- an array. The number of elements in an array cannot exceed the maximum size of
- an "int". The package will work for very small matrices but becomes rather
- inefficient.
-
- A two-stage approach to evaluating matrix expressions is used to improve
- efficiency and reduce use of temporary storage.
-
- The package is designed for version 2 or 3 of C++. It works with Borland (3.1
- & 4.0), Microsoft (7 & 8) and Watcom (10) C++ on a PC and AT&T C++ (2.1 & 3)
- and Gnu G++ (2.3.3, 2.5.8 & 2.6.0). It works with some problems with Zortech
- C++ (version 3.04).
-
-
-
- 1.3 Is this the library for you?
- === == ==== === ======= === ====
-
- Do you
-
- 1: understand * to mean matrix multiply and not element by element multiply
-
- 2: need matrix operators such as * and + defined as operators so you can
- write things like
-
- X = A * (B + C);
-
- 3: need a variety of types of matrices (but not sparse)
-
- 4: need only one element type (float or double)
-
- 5: work with matrices in the range 10 x 10 up to what can be stored in one
- block in memory
-
- 6: tolerate a large package
-
-
- Then maybe this is the right package for you.
-
-
-
- 1.4 Other matrix libraries
- === ===== ====== =========
-
- For commercial packages that support multiple element types, look at M++ from
- Dyad [phone in the USA (800)366-1573, (206)637-9427, fax (206)637-9428], or
- the Rogue Wave matrix package [(800)487-3217, (503)754-3010, fax
- (503)757-6650].
-
- For details of other matrix packages look at the listing from Keith Briggs. A
- recent version of this is in file kbriggs.txt included with this package. Also
- look at Ajay Shah's list of free numerical software in C and C++. The file is
- numcomp-free-c.gz in pub/C-numanal on usc.edu. Nikki Locke produces a list of
- C++ libraries in general - see
- pub/usenet-by-group/comp.lang.c++/c++_FAQ/libraries in rtfm.mit.edu.
-
- Also look on Compuserve in the forums of the various C++ compilers.
-
-
-
- 1.5 Where to find this library
- === ===== == ==== ==== =======
-
-
- * Compuserve (Borland library, zip format)
-
- * SimTel (msdos.cpluspls directory, zip format) - see oak.oakland.edu
-
- * comp.sources.misc on Internet (shar format) - see wuarchive.wustl.edu
-
-
-
-
- 1.6 How to contact the author
- === === == ======= === ======
-
-
- Robert Davies
- 16 Gloucester Street
- Wilton
- Wellington
- New Zealand
-
- "email:" robert.davies@vuw.ac.nz
-
-
-
-
- 1.7 Change history
- === ====== =======
-
- Newmat08 - January, 1995:
-
- Corrections to improve compatibility with Gnu, Watcom. Concatenation of
- matrices. Elementwise products. Option to use compilers supporting exceptions.
- Correction to exception module to allow global declarations of matrices. Fix
- problem with inverse of symmetric matrices. Fix divide-by-zero problem in SVD.
- Include new QR routines. Sum function. Non-linear optimisation.
- GenericMatrices.
-
- Newmat07 - January, 1993
-
- Minor corrections to improve compatibility with Zortech, Microsoft and Gnu.
- Correction to exception module. Additional FFT functions. Some minor increases
- in efficiency. Submatrices can now be used on RHS of =. Option for allowing C
- type subscripts. Method for loading short lists of numbers.
-
-
- Newmat06 - December 1992:
-
- Added band matrices; 'real' changed to 'Real' (to avoid potential conflict in
- complex class); Inject doesn't check for no loss of information; fixes for
- AT&T C++ version 3.0; real(A) becomes A.AsScalar(); CopyToMatrix becomes
- AsMatrix, etc; .c() is no longer required (to be deleted in next version);
- option for version 2.1 or later. Suffix for include files changed to .h; BOOL
- changed to Boolean (BOOL doesn't work in g++ v 2.0); modifications to allow
- for compilers that destroy temporaries very quickly; (Gnu users - see the
- section of compiler performance). Added CleanUp, LinearEquationSolver,
- primitive version of exceptions.
-
-
- Newmat05 - June 1992:
-
- For private release only
-
-
- Newmat04 - December 1991:
-
- Fix problem with G++1.40, some extra documentation
-
-
- Newmat03 - November 1991:
-
- Col and Cols become Column and Columns. Added Sort, SVD, Jacobi, Eigenvalues,
- FFT, real conversion of 1x1 matrix, "Numerical Recipes in C" interface, output
- operations, various scalar functions. Improved return from functions.
- Reorganised setting options in "include.hxx".
-
-
- Newmat02 - July 1991:
-
- Version with matrix row/column operations and numerous additional functions.
-
-
- Matrix - October 1990:
-
- Early version of package.
-
-
-
- 1.8 References
- === ==========
-
- The matrix inverse routine and the sort routines are adapted from "Numerical
- Recipes in C" by Press, Flannery, Teukolsky, Vetterling, published by the
- Cambridge University Press.
-
- Many of the advanced matrix routines are adapted from routines in "Handbook
- for Automatic Computation, Vol II, Linear Algebra" by Wilkinson and Reinsch,
- published by Springer Verlag.
-
-
-
- 2 Getting started
- = ======= =======
-
- Overview 2.1
- Customising 2.2
- Compiler performance 2.3
- Updating from previous versions 2.4
- Example 2.5
- Testing 2.6
-
-
-
-
-
- 2.1 Overview
- === ========
-
- I use .h as the suffix of definition files and .cpp as the suffix of C++
- source files.
-
- You will need to compile all the *.cpp files except example.cpp, the tmt*.cpp
- files, sl_ex.cpp and ex_nl.cpp to get the complete package. Ideally you should
- store the resulting object files as a library. The tmt*.cpp files are used for
- testing [2.6], example.cpp is an example [2.5] and sl_ex.cpp and ex_nl.cpp are
- examples of the non-linear [3.26] solve and optimisation routines.
-
- I include a number of "make" files for compiling the example and the test
- package. See the files section [6] for details. But with Borland and Watcom,
- its pretty quick just to load all the files in the interactive environment by
- pointing and clicking. My Borland "make" files are generated from the
- interactive environment.
-
- Use the large or flat model when you are using a PC. Do not "outline" inline
- functions. You may need to increase the stack size.
-
- The "make" files for the Unix compilers link a .cxx file to each .cpp file
- since some of these compilers do not recognise .cpp as a legitimate extension
- for a C++ file. I suggest you delete this part of the "make" file and rename
- the .cpp files to something your compiler recognises.
-
- My "make" files for Unix systems are for use with 'gmake' rather than 'make'.
- Ordinary 'make' works with them on the Sun but not the Silicon Graphics or HP
- machines.
-
- Your source files that access the newmat you will need to #include one or more
- of the following files.
-
- include.h:
- if you want to access just the compiler options
-
- newmat.h:
- to access just the main matrix library (includes include.h)
-
- newmatap.h:
- to access the advanced matrix routines such as Cholesky decomposition, QR
- triangularisation etc (includes newmat.h)
-
- newmatio.h:
- to access the output routines (includes newmat.h) You can use this only
- with compilers that support the standard input/output routines including
- manipulators. It cannot be used with Zortech or early versions of Gnu.
-
- newmatnl.h:
- to access the non-linear optimisation routines (includes newmat.h)
-
-
-
- See the section on customising [2.2] to see how to edit include.h for your
- environment and the section on compilers [2.3] for any special problems with
- the compiler you are using.
-
-
-
-
- 2.2 Customising
- === ===========
-
- The file include.h sets a variety of options including several compiler
- dependent options. You may need to edit include.h to get the options you
- require. If you are using a compiler different from one I have worked with you
- may have to set up a new section in include.h appropriate for your compiler.
-
- Borland, Turbo, Gnu, Microsoft, Watcom and Zortech are recognised
- automatically. If none of these are recognised a default set of options is
- used. These are fine for AT&T, HPUX and Sun C++. If you using a compiler I
- don't know about you may have to write a new set of options.
-
- Activate the appropriate statement to make the element type float or double.
-
- If you are using the standard style for deleting arrays (AT&T version 2.1 or
- later) make sure Version21 is #defined. If you are using the old style, make
- sure it is not #defined.
-
- There is an option in include.h for selecting whether you use compiler
- supported exceptions, simulated exceptions, or disable exceptions. Use the
- option for compiler supported exceptions if and only if you have set the
- option on your compiler to recognise exceptions. Disabling exceptions
- sometimes helps with compilers that are incompatible with my exception
- simulation scheme.
-
- I suggest you leave the option TEMPS_DESTROYED_QUICKLY activated, even though
- the Gnu compiler is the only one I know about that requires it. This stores
- the "trees" dsecribing matrix expressions on the heap rather than the stack
- and, surprisingly, seems to give better performance. See the discussion in
- newmatb.txt for more explanation.
-
- Leave the option TEMPS_DESTROYED_QUICKLY_R not activated unless you are using
- the Gnu G++ [2.3.3] compiler. This option controls whether the ReturnMatrix
- [3.13] construct uses the stack or the heap. The heap version is rather kludgy
- and probably should be avoided where possible.
-
- The option DO_FREE_CHECK is used for tracking memory leaks and normally should
- not be activated.
-
- Activate SETUP_C_SUBSCRIPTS if you want to use traditional C style element
- access [3.2].
-
-
-
-
- 2.3 Compiler performance
- === ======== ===========
-
- I have tested this library on a number of compilers. Here are the levels of
- success and any special considerations. In most cases I have chosen code that
- works under all the compilers I have access to, but I have had to include some
- specific work-arounds for some compilers. For the MsDos versions, I use a
- 486dx computer running MsDos 6 or windows NT. The unix versions are on a Sun
- Sparc station or a Silicon Graphics or a HP unix workstation. Thanks to
- Victoria University and Industrial Research Ltd for access to the Unix
- machines.
-
- I have set up a block of code for each of the compilers in include.h. Turbo,
- Borland, Gnu, Zortech, Microsoft and Watcom are recognised automatically.
- There is a default option that works for AT&T, Sun C++ 4.0.1 and HPUX. So you
- don't have to make any changes for these compilers. Otherwise you may have to
- build your own set of options in include.h.
-
- AT&T 2.3.1
- Borland 2.3.2
- Gnu G++ 2.3.3
- HPUX 2.3.4
- Microsoft 2.3.5
- Sun 2.3.6
- Watcom 2.3.7
- Zortech 2.3.8
-
-
-
-
- 2.3.1 AT&T
- ===== ====
-
- AT&T C++ 2.1;3.0.1 on a Sun: It works fine with 3.0.1. I haven't been able to
- test the latest version of the library on 2.1. The previous version worked
- fine. Except aggregates are not supported in 2.1 and setjmp.h generated a
- warning message. If you are using "interviews" you may get a conflict with
- Catch. Either #undefine Catch or replace Catch with CATCH throughout my
- package. In AT&T 2.1 you may get an error when you use an expression for the
- single argument when constructing a Vector or DiagonalMatrix or one of the
- Triangular Matrices. You need to evaluate the expression separately.
-
- You cannot run my non-linear [3.26] package with these compilers, because of
- my use of labels.
-
-
-
- 2.3.2 Borland
- ===== =======
-
- Borland C++ 3.1, 4.5: Recently this has been my main development platform, so
- naturally everything works with this compiler. There was a problem with the
- library utility in version 2.0 which is now fixed. You will need to use the
- large model. If you are not debugging, turn off the options that collect
- debugging information. Make sure you don't run Borland's exceptions and my
- simulated exceptions at the same time.
-
- When running my test program with Borland 4.5 under ms-dos you may run out of
- memory. Either compile the test routine to run under "easywin" or use
- simulated exceptions rather than the built in exceptions. Under "easywin" the
- test program indicates a memory leak. I presume this is partly because of the
- way windows organises its heap rather than there being a real problem.
-
- However there does seem to be genuine memory problem when you use the built-in
- exceptions. Under "easywin" the automatic clean-up of objects by the exception
- mechanism does not seem to work. Use my simulated exceptions if this is a
- problem.
-
-
-
- 2.3.3 Gnu G++
- ===== === ===
-
- Gnu G++ 2.3.3, 2.5.8: These mostly work. You must enable the options
- TEMPS_DESTROYED_QUICKLY and TEMPS_DESTROYED_QUICKLY_R. You can't use
- expressions like Matrix(X*Y) in the middle of an expression and (Matrix)(X*Y)
- is unreliable. If you write a function returning a matrix, you MUST use the
- ReturnMatrix [3.13] method described in this documentation. This is because
- g++ destroys temporaries occuring in an expression too soon for the two stage
- way of evaluating expressions that newmat uses. Gnu seems to leave some
- rubbish on the stack. Possibly this is a printer buffer so it may not be a
- bug. You will have problems with versions of Gnu earlier than 2.3.1.
-
- Linux: Gnu G++ 2.5.8 seems a little more touchy than regular G++. But
- basically the package works.
-
- Gnu G++ 2.6.0: Seems OK. There should be better compatibility because version
- 2.6 retains temporaries until the end of the statement instead of destroying
- them immediately following the first access. I suggest you enable option
- TEMPS_DESTROYED_QUICKLY but not TEMPS_DESTROYED_QUICKLY_R.
-
-
-
- 2.3.4 HP-UX
- ===== =====
-
- HP 9000 series HP-UX. I have tried the library on two versions of HP-UX. (I
- don't know the version numbers, the older is a clone of AT&T 3, the newer is
- HP's version with exceptions). Both worked after the modifications described
- in this section except that I couldn't compile the non-linear [3.26] package
- due to my use of labels.
-
- With the older version of the compiler I needed to edit the math.h library
- file to remove a duplicate definition of abs.
-
- With the newer version you can set the +eh option to enable exceptions and
- activate the UseExceptions option in include.h. If you are using my make file,
- you will need to replace CC with CC +eh where ever CC occurs. I recommend that
- you do not do this and either disable exceptions or use my simulated
- exceptions. I get core dumps when I use the built-in exceptions and suspect
- they are not sufficiently debugged as yet.
-
- If you are using my simulated exceptions you may get a mass of error messages
- from the linker about __EH_JMPBUF_TEMP. In this case get file setjmp.h (in
- directory /usr/include/CC ?) and put extern in front of the line
-
- jmp_buf * __EH_JMPBUF_TEMP;
-
- The file setjmp.h is accessed in my file myexcept.h. You may want to change
- the #include statement to access your edited copy of setjmp.h.
-
-
-
- 2.3.5 Microsoft
- ===== =========
-
- Microsoft C++ (7.0, 8.0): Seems to work OK. You must #define
- TEMPS_DESTROYED_QUICKLY owing to a bug in version 7 (at least) of MSC. There
- are some notes in the file include.h on changes to run under version 7. I
- haven't tried the latest version of newmat08 on version 7.
-
- Haven't tried visual C++ yet.
-
-
-
-
- 2.3.6 Sun
- ===== ===
-
- Sun C++ (version 4.0.1): This generally works fine. However, I suspect that
- there is a problem with my non-linear [3.26] package, even though the program
- appears to run correctly, probably because of my use of labels. When I set
- DO_FREE_CHECK, I detect non-existent objects being deleted and the program
- fails if I use simulated exceptions.
-
-
-
- 2.3.7 Watcom
- ===== ======
-
- Watcom C++ (version 10): basically this works fine. Don't try to run Watcom's
- exceptions and my simulated exceptions at the same time.
-
- There does seem to be a problem with expressions such as
-
- X = Matrix(A+B)+C;
-
- Occasionally the temporary object created by Matrix(A+B) is destroyed twice.
- In most cases this does not seem to cause a problem. However, I think one
- should avoid code such as this - in fact, there is generally not much point to
- such code. Alternatively use my simulated exceptions as the problem seems to
- occur only with the built in exceptions enabled.
-
-
-
- 2.3.8 Zortech
- ===== =======
-
- Zortech C++ 3.04: "const" doesn't work correctly with this compiler, so the
- package skips all of the statements Zortech can't handle. Zortech leaves
- rubbish on the heap. I don't know whether this is my programming error or a
- Zortech error or additional printer buffers. Deactivate the option for version
- 2.1 in include.h. Does not support IO manipulators. Otherwise the package
- mostly works, but not completely. Best don't #define TEMPS_DESTROYED_QUICKLY.
- Exceptions and the nric interface don't work. I think some of the problems are
- because Zortech doesn't handle conversions correctly, particularly automatic
- conversions. But, also newmat is just too big for my version of Zortech.
- Zortech runs much more slowly than Borland and Microsoft. Use the large model
- and compile as much as possible with optimisation on to save space. You won't
- be able to get the whole test program to work. Zortech doesn't have
- io-manipulators so you can't compile the example.
-
- I haven't tried the Symantec successors to Zortech.
-
-
-
-
-
- 2.4 Updating newmat08
- === ======== ========
-
- Updating from previous 08 betas 2.4.1
- Updating from previous versions 2.4.2
-
-
- 2.4.1 Updating from previous 08 betas
- ===== ======== ==== ======== == =====
-
-
- If you were using the non-linear optimisation routine in an previous beta,
- note that rowvectors and columnvectors have been swapped in this version of
- newmatnl. You now derive from prototype function classes rather than the
- solution and least squares classes. Simple examples are included with the
- library.
-
- This version includes concatenation operators, elementwise products for
- matrices and GenericMatrices. See the sections on binary operators [3.6] and
- unspecified types [3.16].
-
- There is now no need to explicitly set the AT&T option in include.h.
-
- I have reorganised the make files for AT&T, Gnu, Microsoft and Watcom. See the
- files [6] section.
-
-
- 2.4.2 Updating form previous versions
- ===== ======== ==== ======== ========
-
- This is a minor upgrade on newmat07 to correct errors (one serious) and
- improve compatibility with various compilers. You should upgrade.
-
- * .cxx files are now .cpp files. Some versions of won't accept .cpp. The
- "make" files for Gnu and AT&T link the .cpp files to .cxx files before
- compilation and delete the links after compilation.
-
- * An option [2.2] in include.h allows you to use compiler supported
- exceptions, simulated exceptions or disable exceptions. Edit the file
- include.h to select one of these three options. Don't simulate exceptions if
- you have set your compiler's option to implement exceptions.
-
- * New QR decomposition [3.18] functions.
-
- * A non-linear least squares [3.26] class.
-
- * No need to explicitly set the AT&T option in include.h.
-
- * Concatenation and elementwise multiplication [3.6].
-
- * A new GenericMatrix [3.16] class.
-
- * Sum [3.8] function.
-
- * Some of the make [6] files reorganised.
-
-
- If you are upgrading from newmat06 note the following:
-
- * If you are using << to load a Real into a submatrix change this to =.
-
-
- If you are upgrading from newmat03 or newmat04 note the following
-
- * .hxx files are now .h files
-
- * real changed to Real
-
- * BOOL changed to Boolean
-
- * CopyToMatrix changed to AsMatrix, etc
-
- * real(A) changed to A.AsScalar()
-
-
- The current version is quite a bit longer that newmat04, so if you are almost
- out of space with newmat04, don't throw newmat04 away until you have checked
- your program will work under this version.
-
- See the change history [1.7] for other changes.
-
-
- 2.5 Example
- === =======
-
- An example is given in example.cpp. This gives a simple linear regression
- example using four different algorithms. The correct output is given in
- example.txt. The program carries out a rough check that no memory is left
- allocated on the heap when it terminates. See the section on testing [2.6] for
- a comment on the reliability of this check and the use of the DO_FREE_CHECK
- option.
-
- I include a variety of make files. Use a command like
-
- gmake example -f gnu.mak (Gnu G++)
- gmake example -f cc.mak (AT&T, HPUX, Sun)
- nmake example -f ms_nt.mak (Microsoft C++ 8.0)
- make -f ex_b.mak (Borland C++ 3.1)
- make -f ex_bc45.mak (Borland C++ 4.5)
- wmake example.exe -f watcom.mak (Watcom C++ 10A)
- wmake example.exe -f watco_nt.mak (Watcom C++ 10A)
-
- The Borland files were derived from the project file and you will have to edit
- these to suit your environment. The file ex_bc45.mak is for making a windows
- NT executable program. The Microsoft file is for the version of C++ that came
- with the Windows NT 3.1 development kit. The second Watcom file is for making
- a Windows NT executable.
-
- ------------------------------------------------------------------------------
- This example uses io manipulators. It will not work with a compiler that does
- not support the standard io manipulators.
- ------------------------------------------------------------------------------
-
-
-
- 2.6 Testing
- === =======
-
- The library package contains a comprehensive test program in the form of a
- series of files with names of the form tmt?.cxx. The files consist of a large
- number of matrix formulae all of which evaluate to zero (except the first one
- which is used to check that we are detecting non-zero matrices). The printout
- should state that it has found just one non-zero matrix.
-
- Various versions of the make file (extension .mak) are included with the
- package. See the section on files [6].
-
- The program also allocates and deletes a large block and small block of memory
- before it starts the main testing and then at the end of the test. It then
- checks that the blocks of memory were allocated in the same place. If not then
- one suspects that there has been a memory leak. i.e. a piece of memory has
- been allocated and not deleted.
-
- This is not completely foolproof. Programs may allocate extra print buffers
- while the program is running. I have tried to overcome this by doing a print
- before I allocate the first memory block. Programs may allocate memory for
- different sized items in different places, or might not allocate items
- consecutively. Or they might mix the items with memory blocks from other
- programs. Nevertheless, I seem to get consistent answers from many of the
- compilers I am working with, so I think this is a worthwhile test.
-
- If the DO_FREE_CHECK [2.2] option in include.h is activated, the program
- checks that each 'new' is balanced with exactly one 'delete'. This provides a
- more definitive test of no memory leaks. There are additional statements in
- myexcept.cpp which can be activated to print out details of the memory being
- allocated and released.
-
- Several of the files have a line defining 'REPORT' that can be activated
- (deactivate the dummy version). This gives a printout of the number of times
- each of the 'REPORT' statements in the file is accessed. Use a grep with line
- numbers to locate the lines on which 'REPORT' occurs and compare these with
- the lines that the printout shows were actually accessed.
-
-
- 3 Reference manual
- = ========= ======
-
- Constructors 3.1
- Accessing elements 3.2
- Assignment and copying 3.3
- Entering values 3.4
- Unary operations 3.5
- Binary operations 3.6
- Matrix and scalar ops 3.7
- Scalar functions 3.8
- Submatrices 3.9
- Change dimension 3.10
- Change type 3.11
- Multiple matrix solve 3.12
- Memory management 3.13
- Efficiency 3.14
- Output 3.15
- Accessing unspecified type 3.16
- Cholesky decomposition 3.17
- QR decomposition 3.18
- Singular value decomposition 3.19
- Eigenvalue decomposition 3.20
- Sorting 3.21
- Fast Fourier transform 3.22
- Numerical recipes in C 3.23
- Exceptions 3.24
- Cleanup following exception 3.25
- Non-linear applications 3.26
-
-
- 3.1 Constructors
- === ============
-
- To construct an m x n matrix, 'A', (m and n are integers) use
-
- Matrix A(m,n);
-
- The UpperTriangularMatrix, LowerTriangularMatrix, SymmetricMatrix and
- DiagonalMatrix types are square. To construct an n x n matrix use, for example
-
- UpperTriangularMatrix UT(n);
- LowerTriangularMatrix LT(n);
- SymmetricMatrix S(n);
- DiagonalMatrix D(n);
-
- Band matrices need to include bandwidth information in their constructors.
-
- BandMatrix BM(n, lower, upper);
- UpperBandMatrix UB(n, upper);
- LowerBandMatrix LB(n, lower);
- SymmetrixBandMatrix SB(n, lower);
-
- The integers upper and lower are the number of non-zero diagonals above and
- below the diagonal (excluding the diagonal) respectively.
-
- The RowVector and ColumnVector types take just one argument in their
- constructors:
-
- RowVector RV(n);
- ColumnVector CV(n);
-
- You can also construct vectors and matrices without specifying the dimension.
- For example
-
- Matrix A;
-
- In this case the dimension must be set by an assignment statement [3.3] or a
- re-dimension statement [3.10].
-
- You can also use a constructor to set a matrix equal to another matrix or
- matrix expression.
-
- Matrix A = UT;
- Matrix A = UT * LT;
-
- Only conversions that don't lose information are supported - eg you cannot
- convert an upper triangular matrix into a diagonal matrix using =.
-
-
-
- 3.2 Accessing elements
- === ========= ========
-
- Elements are accessed by expressions of the form 'A(i,j)' where i and j run
- from 1 to the appropriate dimension. Access elements of vectors with just one
- argument. Diagonal matrices can accept one or two subscripts.
-
- This is different from the earliest version of the package in which the
- subscripts ran from 0 to one less than the appropriate dimension. Use
- 'A.element(i,j)' if you want this earlier convention.
-
- 'A(i,j)' and 'A.element(i,j)' can appear on either side of an = sign.
-
- If you activate the '#define SETUP_C_SUBSCRIPTS' in 'include.h' you can also
- access elements using the tradition C style notation. That is 'A[i][j]' for
- matrices (except diagonal) and 'V[i]' for vectors and diagonal matrices. The
- subscripts start at zero (ie like element) and there is no range checking.
- Because of the possibility of confusing 'V(i)' and 'V[i]', I suggest you do
- not activate this option unless you really want to use it.
-
-
- 3.3 Assignment and copying
- === ========== === =======
-
- The operator = is used for copying matrices, converting matrices, or
- evaluating expressions. For example
-
- A = B; A = L; A = L * U;
-
- Only conversions that don't lose information are supported. The dimensions of
- the matrix on the left hand side are adjusted to those of the matrix or
- expression on the right hand side. Elements on the right hand side which are
- not present on the left hand side are set to zero.
-
- The operator << can be used in place of = where it is permissible for
- information to be lost.
-
- For example
-
- SymmetricMatrix S; Matrix A;
- ......
- S << A.t() * A;
-
- is acceptable whereas
-
- S = A.t() * A; // error
-
- will cause a runtime error since the package does not (yet?) recognise
- 'A.t()*A' as symmetric.
-
- Note that you can not use << with constructors. For example
-
- SymmetricMatrix S << A.t() * A; // error
-
- does not work.
-
- Also note that << cannot be used to load values from a full matrix into a band
- matrix, since it will be unable to determine the bandwidth of the band matrix.
-
- A third copy routine is used in a similar role to =. Use
-
- A.Inject(D);
-
- to copy the elements of 'D' to the corresponding elements of 'A' but leave the
- elements of 'A' unchanged if there is no corresponding element of 'D' (the =
- operator would set them to 0). This is useful, for example, for setting the
- diagonal elements of a matrix without disturbing the rest of the matrix.
- Unlike = and <<, Inject does not reset the dimensions of 'A', which must match
- those of 'D'. Inject does not test for no loss of information.
-
- You cannot replace 'D' by a matrix expression. The effect of 'Inject(D)'
- depends on the type of 'D'. If 'D' is an expression it might not be obvious to
- the user what type it would have. So I thought it best to disallow
- expressions.
-
- Inject can be used for loading values from a regular matrix into a band
- matrix. (Don't forget to zero any elements of the left hand side that will not
- be set by the loading operation).
-
- Both << and Inject can be used with submatrix expressions on the left hand
- side. See the section on submatrices [3.9].
-
- To set the elements of a matrix to a scalar use operator =
-
- Real r; Matrix A(m,n);
- ......
- Matrix A(m,n); A = r;
-
-
-
-
- 3.4 Entering values
- === ======== ======
-
- You can load the elements of a matrix from an array:
-
- Matrix A(3,2);
- Real a[] = { 11,12,21,22,31,33 };
- A << a;
-
- This construction does not check that the numbers of elements match correctly.
- This version of << can be used with submatrices on the left hand side. It is
- not defined for band matrices.
-
- Alternatively you can enter short lists using a sequence of numbers separated
- by << .
-
- Matrix A(3,2);
- A << 11 << 12
- << 21 << 22
- << 31 << 32;
-
- This does check for the correct total number of entries, although the message
- for there being insufficient numbers in the list may be delayed until the end
- of the block or the next use of this construction. This does not work for band
- matrices or submatrices, or for long lists. Also try to restrict its use to
- numbers. You can include expressions, but these must not call a function which
- includes the same construction.
-
-
-
- 3.5 Unary operators
- === ===== =========
-
- The package supports unary operations
-
- X = -A // change sign of elements
- X = A.t() // transpose
- X = A.i() // inverse (of square matrix A)
-
-
-
-
- 3.6 Binary operators
- === ====== =========
-
- The package supports binary operations
-
- X = A + B // matrix addition
- X = A - B // matrix subtraction
- X = A * B // matrix multiplication
- X = A.i() * B // equation solve (square matrix A)
- X = A | B // concatenate horizontally (concatenate the rows)
- X = A & B // concatenate vertically (concatenate the columns)
- X = SP(A, B) // elementwise product of A and B (Schur product)
-
-
- Notes:
-
- * If you are doing repeated multiplication. For example 'A*B*C', use brackets
- to force the order of evaluation to minimize the number of operations. If 'C'
- is a column vector and 'A' is not a vector, then it will usually reduce the
- number of operations to use 'A*(B*C)'.
-
- * In the equation solve example case the inverse is not explicitly
- calculated. An LU decomposition of 'A' is performed and this is applied to
- 'B'. This is more efficient than calculating the inverse and then multiplying.
- See also multiple matrix solving [3.12].
-
- * The package does not (yet?) recognise 'B*A.i()' as an equation solve and
- the inverse of 'A' would be calculated. It is probably better to use
- '(A.t().i()*B.t()).t()'.
-
- * Horizontal or vertical concatenation returns a result of type Matrix,
- RowVector or ColumnVector.
-
- * If 'A' is m x p, 'B' is m x q, then 'A | B' is m x (p+q) with the k-th row
- being the elements of the k-th row of 'A' followed by the elements of the k-th
- row of 'B'.
-
- * If 'A' is p x n, 'B' is q x n, then 'A & B' is (p+q) x n with the k-th
- column being the elements of the k-th column of 'A' followed by the elements
- of the k-th column of 'B'.
-
- * For complicated concatenations of matrices, consider instead using
- submatrices [3.9].
-
-
-
-
- 3.7 Matrix and scalar
- === ====== === ======
-
- The following expression multiplies the elements of a matrix 'A' by a scalar
- f: 'A * f;' Likewise one can divide the elements of a matrix 'A' by a scalar
- f:' A / f;'
-
- The expressions 'A + f' and 'A - f' add or subtract a rectangular matrix of
- the same dimension as 'A' with elements equal to 'f' to or from the matrix
- 'A'.
-
- In each case the matrix must be the first term in the expression. Expressions
- such 'f + A' or 'f * A' are not recognised (yet?).
-
-
-
-
- 3.8 Scalar functions of a matrix
- === ====== ========= == = ======
-
-
- int m = A.Nrows(); // number of rows
- int n = A.Ncols(); // number of columns
- Real ssq = A.SumSquare(); // sum of squares of elements
- Real sav = A.SumAbsoluteValue(); // sum of absolute values
- Real s = A.Sum(); // sum of values
- Real mav = A.MaximumAbsoluteValue(); // maximum of absolute values
- Real norm = A.Norm1(); // maximum of sum of absolute
- values of elements of a column
- Real norm = A.NormInfinity(); // maximum of sum of absolute
- values of elements of a row
- Real t = A.Trace(); // trace
- LogandSign ld = A.LogDeterminant(); // log of determinant
- Boolean z = A.IsZero(); // test all elements zero
- MatrixType mt = A.Type(); // type of matrix
- Real* s = Store(); // pointer to array of elements
- int l = Storage(); // length of array of elements
-
- 'A.LogDeterminant()' returns a value of type LogandSign. If ld is of type
- LogAndSign use
-
- ld.Value() to get the value of the determinant
- ld.Sign() to get the sign of the determinant (values 1, 0, -1)
- ld.LogValue() to get the log of the absolute value.
-
- 'A.IsZero()' returns Boolean value TRUE if the matrix 'A' has all elements
- equal to 0.0.
-
- 'MatrixType mt = A.Type()' returns the type of a matrix. Use '(char*)mt' to
- get a string (UT, LT, Rect, Sym, Diag, Band, UB, LB, Crout, BndLU) showing
- the type (Vector types are returned as Rect).
-
- The versions Sum(A), SumSquare(A), SumAbsoluteValue(A),
- MaximumAbsoluteValue(A), Trace(A), LogDeterminant(A), Norm1(A),
- NormInfinity(A) can be used in place of A.Sum(), A.SumSquare(),
- A.SumAbsoluteValue(), A.MaximumAbsoluteValue(), A.Trace(), A.LogDeterminant(),
- A.Norm1(), A.NormInfinity().
-
-
-
- 3.9 Submatrices
- === ===========
-
-
- A.SubMatrix(fr,lr,fc,lc)
-
- This selects a submatrix from 'A'. The arguments fr,lr,fc,lc are the first
- row, last row, first column, last column of the submatrix with the numbering
- beginning at 1. This may be used in any matrix expression or on the left hand
- side of =, << or Inject. Inject does not check no information loss. You can
- also use the construction
-
- Real c; .... A.SubMatrix(fr,lr,fc,lc) = c;
-
- to set a submatrix equal to a constant.
-
- The follwing are variants of SubMatrix:
-
- A.SymSubMatrix(f,l) // This assumes fr=fc and lr=lc.
- A.Rows(f,l) // select rows
- A.Row(f) // select single row
- A.Columns(f,l) // select columns
- A.Column(f) // select single column
-
- In each case f and l mean the first and last row or column to be selected
- (starting at 1).
-
- If SubMatrix or its variant occurs on the right hand side of an = or << or
- within an expression its type is as follows
-
- A.Submatrix(fr,lr,fc,lc): If A is RowVector or
- ColumnVector then same type
- otherwise type Matrix
- A.SymSubMatrix(f,l): Same type as A
- A.Rows(f,l): Type Matrix
- A.Row(f): Type RowVector
- A.Columns(f,l): Type Matrix
- A.Column(f): Type ColumnVector
-
- If SubMatrix or its variant appears on the left hand side of = or << , think
- of its type being Matrix. Thus 'L.Row(1)' where 'L' is LowerTriangularMatrix
- expects 'L.Ncols()' elements even though it will use only one of them. If you
- are using = the program will check for no loss of data.
-
- If you are are using the submatrix facility to build a matrix from a small
- number of components, consider instead using the concatenation operators
- [3.6].
-
-
-
- 3.10 Change dimensions
- ==== ====== ==========
-
- The following operations change the dimensions of a matrix. The values of the
- elements are lost.
-
- A.ReDimension(nrows,ncols); // for type Matrix or nricMatrix
- A.ReDimension(n); // for all other types, except Band
- A.ReDimension(n,lower,upper); // for BandMatrix
- A.ReDimension(n,lower); // for LowerBandMatrix
- A.ReDimension(n,upper); // for UpperBandMatrix
- A.ReDimension(n,lower); // for SymmetricBandMatrix
-
- Use 'A.CleanUp()' to set the dimensions of 'A' to zero and release all the
- heap memory.
-
- Remember that 'ReDimension' destroys values. If you want to 'ReDimension', but
- keep the values in the bit that is left use something like
-
- ColumnVector V(100);
- ... // load values
- V = V.Rows(1,50); // to get first 50 values.
-
- If you want to extend a matrix or vector use something like
-
- ColumnVector V(50);
- ... // load values
- { V.Release(); ColumnVector X=V; V.ReDimension(100); V.Rows(1,50)=X; }
- // V now length 100
-
-
-
-
- 3.11 Change type
- ==== ====== ====
-
- The following functions interpret the elements of a matrix (stored row by row)
- to be a vector or matrix of a different type. Actual copying is usually
- avoided where these occur as part of a more complicated expression.
-
- A.AsRow()
- A.AsColumn()
- A.AsDiagonal()
- A.AsMatrix(nrows,ncols)
- A.AsScalar()
-
- The expression 'A.AsScalar()' is used to convert a 1 x 1 matrix to a scalar.
-
-
-
- 3.12 Multiple matrix solve
- ==== ======== ====== =====
-
- If 'A' is a square or symmetric matrix use
-
- CroutMatrix X = A; // carries out LU decomposition
- Matrix AP = X.i()*P; Matrix AQ = X.i()*Q;
- LogAndSign ld = X.LogDeterminant();
-
- rather than
-
- Matrix AP = A.i()*P; Matrix AQ = A.i()*Q;
- LogAndSign ld = A.LogDeterminant();
-
- since each operation will repeat the LU decomposition.
-
- If 'A' is a BandMatrix or a SymmetricBandMatrix begin with
-
- BandLUMatrix X = A; // carries out LU decomposition
-
- A CroutMatrix or a BandLUMatrix can't be manipulated or copied. Use references
- as an alternative to copying.
-
- Alternatively use
-
- LinearEquationSolver X = A;
-
- This will choose the most appropiate decomposition of 'A'. That is, the band
- form if 'A' is banded; the Crout decomposition if 'A' is square or symmetric
- and no decomposition if 'A' is triangular or diagonal. If you want to use the
- LinearEquationSolver '#include newmatap.h'.
-
-
-
- 3.13 Memory management
- ==== ====== ==========
-
- The package does not support delayed copy. Several strategies are required to
- prevent unnecessary matrix copies.
-
- Where a matrix is called as a function argument use a constant reference. For
- example
-
- YourFunction(const Matrix& A)
-
- rather than
-
- YourFunction(Matrix A)
-
-
- Skip the rest of this section on your first reading.
- ------------------------------------------------------------------------------
- Gnu g++ (< 2.6) users please read on; if you are returning matrix values from
- a function, then you must use the ReturnMatrix construct.
- ------------------------------------------------------------------------------
-
- A second place where it is desirable to avoid unnecessary copies is when a
- function is returning a matrix. Matrices can be returned from a function with
- the return command as you would expect. However these may incur one and
- possibly two copyings of the matrix. To avoid this use the following
- instructions.
-
- Make your function of type ReturnMatrix . Then precede the return statement
- with a Release statement (or a ReleaseAndDelete statement if the matrix was
- created with new). For example
-
-
- ReturnMatrix MakeAMatrix()
- {
- Matrix A;
- ......
- A.Release(); return A;
- }
-
- or
-
- ReturnMatrix MakeAMatrix()
- {
- Matrix* m = new Matrix;
- ......
- m->ReleaseAndDelete(); return *m;
- }
-
- If your compiler objects to this code, replace the return statements with
-
- return A.ForReturn();
-
- or
-
- return m->ForReturn();
-
-
- If you are using AT&T C++ you may wish to replace 'return A;' by return
- '(ReturnMatrix)A;' to avoid a warning message; but this will give a runtime
- error with Gnu. (You can't please everyone.)
- ------------------------------------------------------------------------------
- Do not forget to make the function of type ReturnMatrix; otherwise you may get
- incomprehensible run-time errors.
- ------------------------------------------------------------------------------
- You can also use '.Release()' or '->ReleaseAndDelete()' to allow a matrix
- expression to recycle space. Suppose you call
-
- A.Release();
-
- just before 'A' is used just once in an expression. Then the memory used by
- 'A' is either returned to the system or reused in the expression. In either
- case, 'A''s memory is destroyed. This procedure can be used to improve
- efficiency and reduce the use of memory.
-
- Use '->ReleaseAndDelete' for matrices created by new if you want to completely
- delete the matrix after it is accessed.
-
-
-
- 3.14 Efficiency
- ==== ==========
-
- The package tends to be not very efficient for dealing with matrices with
- short rows. This is because some administration is required for accessing rows
- for a variety of types of matrices. To reduce the administration a special
- multiply routine is used for rectangular matrices in place of the generic one.
- Where operations can be done without reference to the individual rows (such as
- adding matrices of the same type) appropriate routines are used.
-
- When you are using small matrices (say smaller than 10 x 10) you may find it
- faster to use rectangular matrices rather than the triangular or symmetric
- ones.
-
-
-
- 3.15 Output
- ==== ======
-
- To print a matrix use an expression like
-
- Matrix A;
- ......
- cout << setw(10) << setprecision(5) << A;
-
- This will work only with systems that support the AT&T input/output routines
- including manipulators. You need to #include the file newmat9.h.
-
- The present version of this routine is useful only for matrices small enough
- to fit within a page or screen width.
-
- To print several vectors or matrices in columns use a concatenation operator
- [3.6]:
-
- Matrix A, B;
- .....
- cout << setw(10) << setprecision(5) << (A | B);
-
-
-
-
- 3.16 Unspecified type
- ==== =========== ====
-
- Skip this section on your first reading.
-
- If you want to work with a matrix of unknown type, say in a function. You can
- construct a matrix of type 'GenericMatrix'. Eg
-
- Matrix A;
- ..... // put some values in A
- GenericMatrix GM = A;
-
- A GenericMatrix matrix can be used anywhere where a matrix expression can be
- used and also on the left hand side of an '='. You can pass any type of matrix
- (excluding the Crout and BandLUMatrix types) to a 'const GenericMatrix&'
- argument in a function. However most scalar functions including Nrows(),
- Ncols(), Type() and element access do not work with it. Nor does the
- ReturnMatrix construct. See also the paragraph on LinearEquationSolver [3.12].
-
- An alternative and less flexible approach is to use Basematrix or
- GeneralMatrix.
-
- Suppose you wish to write a function which accesses a matrix of unknown type
- including expressions (eg 'A*B'). Then use a layout similar to the following:
-
- void YourFunction(BaseMatrix& X)
- {
- GeneralMatrix* gm = X.Evaluate(); // evaluate an expression
- // if necessary
- ........ // operations on *gm
- gm->tDelete(); // delete *gm if a temporary
- }
-
- See, as an example, the definitions of 'operator<<' in newmat9.cxx.
-
- Under certain circumstances; particularly where 'X' is to be used just once in
- an expression you can leave out the 'Evaluate()' statement and the
- corresponding 'tDelete()'. Just use 'X' in the expression.
-
- If you know YourFunction will never have to handle a formula as its argument
- you could also use
-
- void YourFunction(const GeneralMatrix& X)
- {
- ........ // operations on X
- }
-
- Do not try to construct a GeneralMatrix or BaseMatrix.
-
-
-
- 3.17 Cholesky decomposition
- ==== ======== =============
-
- Suppose S is symmetric and positive definite. Then there exists a unique lower
- triangular matrix L such that L * L.t() = S. To calculate this use
-
- SymmetricMatrix S;
- ......
- LowerTriangularMatrix L = Cholesky(S);
-
- If S is a symmetric band matrix then L is a band matrix and an alternative
- procedure is provied for carrying out the decomposition:
-
- SymmetricBandMatrix S;
- ......
- LowerBandMatrix L = Cholesky(S);
-
-
-
-
- 3.18 QR decomposition
- ==== == =============
-
- This is a variant on the usual QR transformation.
-
- Start with matrix
-
- / 0 0 \ s
- \ X Y / n
-
- s t
-
- Our version of the QR decomposition multiplies this matrix by an orthogonal
- matrix Q to get
-
- / U M \ s
- \ 0 Z / n
-
- s t
-
- where 'U' is upper triangular (the R of the QR transform).
-
- This is good for solving least squares problems: choose b (matrix or row
- vector) to minimize the sum of the squares of the elements of
-
- Y - X*b
-
- Then choose 'b = U.i()*M;' The residuals 'Y - X*b' are in 'Z'.
-
- This is the usual QR transformation applied to the matrix 'X' with the square
- zero matrix attached concatenated on top of it. It gives the same triangular
- matrix as the QR transform applied directly to 'X' and generally seems to work
- in the same way as the usual QR transform. However it fits into the matrix
- package better and also gives us the residuals directly. It turns out to be
- essentially a modified Gram-Schmidt decomposition.
-
- Two routines are provided:
-
- QRZ(X, U);
-
- replaces 'X' by orthogonal columns and forms 'U'.
-
- QRZ(X, Y, M);
-
- uses 'X' from the first routine, replaces 'Y' by 'Z' and forms 'M'.
-
- The are also two routines 'QRZT(X, L)' and 'QRZT(X, Y, M)' which do the same
- decomposition on the transposes of all these matrices. QRZT replaces the
- routines HHDecompose in earlier versions of newmat. HHDecompose is still
- defined but just calls QRZT.
-
-
-
- 3.19 Singular value decomposition
- ==== ======== ===== =============
-
- The singular value decomposition of an m x n matrix 'A' (where m >= n) is a
- decomposition
-
- A = U * D * V.t()
-
- where 'U' is m x n with 'U.t() * U' equalling the identity, 'D' is an n x n
- diagonal matrix and 'V' is an n x n orthogonal matrix.
-
- Singular value decompositions are useful for understanding the structure of
- ill-conditioned matrices, solving least squares problems, and for finding the
- eigenvalues of 'A.t() * A'.
-
- To calculate the singular value decomposition of 'A' (with m >= n) use one of
-
- SVD(A, D, U, V); // U (= A is OK)
- SVD(A, D);
- SVD(A, D, U); // U (= A is OK)
- SVD(A, D, U, FALSE); // U (can = A) for workspace only
- SVD(A, D, U, V, FALSE); // U (can = A) for workspace only
-
- The values of 'A' are not changed unless 'A' is also inserted as the third
- argument.
-
-
-
- 3.20 Eigenvalue decomposition
- ==== ========== =============
-
- An eigenvalue decomposition of a symmetric matrix 'A' is a decomposition
-
- A = V * D * V.t()
-
- where 'V' is an orthogonal matrix and 'D' is a diagonal matrix.
-
- Eigenvalue analyses are used in a wide variety of engineering, statistical and
- other mathematical analyses.
-
- The package includes two algorithms: Jacobi and Householder. The first is
- extremely reliable but much slower than the second.
-
- The code is adapted from routines in "Handbook for Automatic Computation, Vol
- II, Linear Algebra" by Wilkinson and Reinsch, published by Springer Verlag.
-
-
- Jacobi(A,D,S,V); // A, S symmetric; S is workspace,
- // S = A is OK; V is a matrix
- Jacobi(A,D); // A symmetric
- Jacobi(A,D,S); // A, S symmetric; S is workspace,
- // S = A is OK
- Jacobi(A,D,V); // A symmetric; V is a matrix
-
- EigenValues(A,D); // A symmetric
- EigenValues(A,D,S); // A, S symmetric; S is for back
- // transforming, S = A is OK
- EigenValues(A,D,V); // A symmetric; V is a matrix
-
- The values of 'A' are not changed unless 'A' is also inserted as the third
- argument. If you need eigenvectors use one of the forms with matrix 'V'. The
- eigenvectors are returned as the columns of 'V'.
-
-
-
-
- 3.21 Sorting
- ==== =======
-
- To sort the values in a matrix or vector, 'A', (in general this operation
- makes sense only for vectors and diagonal matrices) use
-
- SortAscending(A);
-
- or
-
- SortDescending(A);
-
- I use the Shell-sort algorithm. This is a medium speed algorithm, you might
- want to replace it with something faster if speed is critical and your
- matrices are large.
-
-
-
- 3.22 Fast Fourier transform
- ==== ==== ======= =========
-
-
- FFT(X, Y, F, G); // F=X and G=Y are OK
-
- where X, Y, F, G are column vectors. X and Y are the real and imaginary input
- vectors; F and G are the real and imaginary output vectors. The lengths of X
- and Y must be equal and should be the product of numbers less than about 10
- for fast execution.
-
- The formula is
-
- n-1
- h[k] = SUM z[j] exp (-2 pi i jk/n)
- j=0
-
- where z[j] is stored complex and stored in X(j+1) and Y(j+1). Likewise h[k] is
- complex and stored in F(k+1) and G(k+1). The fast Fourier algorithm takes
- order n log(n) operations (for "good" values of n) rather than n**2 that
- straight evaluation would take.
-
- I use the method of Carl de Boor (1980), "Siam J Sci Stat Comput", pp 173-8.
- The sines and cosines are calculated explicitly. This gives better accuracy,
- at an expense of being a little slower than is otherwise possible.
-
- Related functions
-
- FFTI(F, G, X, Y); // X=F and Y=G are OK
- RealFFT(X, F, G);
- RealFFTI(F, G, X);
-
- 'FFTI' is the inverse trasform for 'FFT'. 'RealFFT' is for the case when the
- input vector is real, that is Y = 0. I assume the length of X, denoted by n,
- is even. The program sets the lengths of F and G to n/2 + 1. 'RealFFTI' is the
- inverse of 'RealFFT'.
-
-
-
- 3.23 Interface to Numerical Recipes in C
- ==== ========= == ========= ======= == =
-
- This package can be used with the vectors and matrices defined in "Numerical
- Recipes in C". You need to edit the routines in Numerical Recipes so that the
- elements are of the same type as used in this package. Eg replace float by
- double, vector by dvector and matrix by dmatrix, etc. You will also need to
- edit the function definitions to use the version acceptable to your compiler.
- Then enclose the code from Numerical Recipes in extern "C" { ... }. You will
- also need to include the matrix and vector utility routines.
-
- Then any vector in Numerical Recipes with subscripts starting from 1 in a
- function call can be accessed by a RowVector, ColumnVector or DiagonalMatrix
- in the present package. Similarly any matrix with subscripts starting from 1
- can be accessed by an nricMatrix in the present package. The class
- nricMatrix is derived from Matrix and can be used in place of Matrix. In each
- case, if you wish to refer to a RowVector, ColumnVector, DiagonalMatrix or
- nricMatrix X in an function from Numerical Recipes, use X.nric() in the
- function call.
-
- Numerical Recipes cannot change the dimensions of a matrix or vector. So
- matrices or vectors must be correctly dimensioned before a Numerical Recipes
- routine is called.
-
- For example
-
- SymmetricMatrix B(44);
- ..... // load values into B
- nricMatrix BX = B; // copy values to an nricMatrix
- DiagonalMatrix D(44); // Matrices for output
- nricMatrix V(44,44); // correctly dimensioned
- int nrot;
- jacobi(BX.nric(),44,D.nric(),V.nric(),&nrot);
- // jacobi from NRIC
- cout << D; // print eigenvalues
-
-
-
-
- 3.24 Exceptions
- ==== ==========
-
- This package includes a partial implementation of exceptions for compilers
- which do not support C++ exceptions. I used Carlos Vidal's article in the
- September 1992 "C Users Journal" as a starting point.
-
- See customising [2.2] for selecting the correct exception option.
-
- See the section on error messages [4] for some notes on the messages generated
- by the exceptions.
-
- The rest of this section describes my exception simulation package. But see
- the end of the section for controlling the action after an exception has been
- generated.
-
- Newmat does a partial clean up of memory following throwing an exception - see
- the next section. However, the present version will leave a little heap memory
- unrecovered under some circumstances. I would not expect this to be a major
- problem, but it is something that needs to be sorted out.
-
- The functions/macros I define are Try, Throw, Catch, CatchAll and
- CatchAndThrow. Try, Throw, Catch and CatchAll correspond to try, throw, catch
- and catch(...) in the C++ standard. A list of Catch clauses must be terminated
- by either CatchAll or CatchAndThrow but not both. Throw takes an Exception as
- an argument or takes no argument (for passing on an exception). I do not have
- a version of Throw for specifying which exceptions a function might throw.
- Catch takes an exception class name as an argument; CatchAll and CatchAndThrow
- don't have any arguments. Try, Catch and CatchAll must be followed by blocks
- enclosed in curly brackets.
-
- I have added another macro Bounce to mean a rethrow, Throw(). This was
- necessary to enable the package to be compatible with both my exception
- package and C++ exceptions.
-
- All Exceptions must be derived from a class, Exception, defined in newmat and
- can contain only static variables. See the examples in newmat if you want to
- define additional exceptions.
-
- I have defined 5 clases of exceptions for users (there are others but I
- suggest you stick to these ones):
-
- SpaceException Insufficient space on the heap
- ProgramException Errors such as out of range index or
- incompatible matrix types or
- dimensions
- ConvergenceException Iterative process does not converge
- DataException Errors such as attempting to invert a
- singular matrix
- InternalException Probably a programming error in newmat
-
- For each of these exception classes, I have defined a member function 'void
- SetAction(int)'. If you call 'SetAction(1)', and a corresponding exception
- occurs, you will get an error message. If there is a Catch clause for that
- exception, execution will be passed to that clause, otherwise the program will
- exit. If you call 'SetAction(0)' you will get the same response, except that
- there will be no error message. If you call 'SetAction(-1)', you will get the
- error message but the program will always exit.
-
-
-
- 3.25 Cleanup after an exception
- ==== ======= ===== == =========
-
- The exception mechanisms in newmat are based on the C functions setjmp and
- longjmp. These functions do not call destructors so can lead to garbage being
- left on the heap. (I refer to memory allocated by "new" as heap memory). For
- example, when you call
-
- Matrix A(20,30);
-
- a small amount of space is used on the stack containing the row and column
- dimensions of the matrix and 600 doubles are allocated on the heap for the
- actual values of the matrix. At the end of the block in which A is declared,
- the destructor for A is called and the 600 doubles are freed. The locations on
- the stack are freed as part of the normal operations of the stack. If you
- leave the block using a longjmp command those 600 doubles will not be freed
- and will occupy space until the program terminates.
-
- To overcome this problem newmat keeps a list of all the currently declared
- matrices and its exception mechanism will return heap memory when you do a
- Throw and Catch.
-
- However it will not return heap memory from objects from other packages. If
- you want the mechanism to work with another class you will have to do four
- things:
-
- 1: derive your class from class Janitor defined in except.h;
-
- 2: define a function 'void CleanUp()' in that class to return all heap
- memory;
-
- 3: include the following lines in the class definition
-
- public:
- void* operator new(size_t size)
- { do_not_link=TRUE; void* t = ::operator new(size); return t; }
- void operator delete(void* t) { ::operator delete(t); }
-
- 4: be sure to include a copy constructor in you class definition, that is,
- something like
-
- X(const X&);
-
-
- Note that the function 'CleanUp()' does somewhat the same duties as the
- destructor. However 'CleanUp()' has to do the "cleaning" for the class you are
- working with and also the classes it is derived from. So it will often be
- wrong to use exactly the same code for both 'CleanUp()' and the destructor or
- to define your destructor as a call to 'CleanUp()'.
-
-
-
-
- 3.26 Non-linear applications
- ==== ========== ============
-
- Files solution.h, solution.cpp contain a class for solving for x in y = f(x)
- where x is a one-dimensional continuous monotonic function. This is not a
- matrix thing at all but is included because it is a useful thing and because
- it is a simpler version of the technique used in the non-linear least squares.
-
- Files newmatnl.h, newmatnl.cpp contain a series of classes for non-linear
- least squares, to be extended to maximum likelihood in a later release.
-
- Documentation for both of these is in the definition files. Simple examples
- are in sl_ex.cpp and nl_ex.cpp.
-
- These packages do not work with the AT&T [2.3.1] and HPUX [2.3.4] compilers
- and newmatnl is questionable under Sun 4.0.1 [2.3.6].
-
-
-
- 4 Error messages
- = ===== ========
-
- Most error messages are self-explanatory. The message gives the size of the
- matrices involved. Matrix types are referred to by the following codes:
-
- Matrix or vector 1
- Symmetric matrix 5
- Band matrix 9
- Symmetric band matrix 13
- Lower triangular matrix 17
- Lower triangular band matrix 25
- Upper triangular matrix 33
- Upper triangular band matrix 41
- Diagonal matrix 63
- Crout matrix (LU matrix) 65
- Band LU matrix 73
-
- Other codes should not occur.
-
- See the section on exceptions [3.24] for more details on the structure of the
- exception classes.
-
- I have defined a class Tracer that is intended to help locate the place where
- an error has occurred. At the beginning of a function I suggest you include a
- statement like
-
- Tracer tr("name");
-
- where name is the name of the function. This name will be printed as part of
- the error message, if an exception occurs in that function, or in a function
- called from that function. You can change the name as you proceed through a
- function with the ReName function
-
- tr.ReName("new name");
-
- if, for example, you want to track progress through the function.
-
-
-
-
- 5 Bugs
- = ====
-
-
- * Small memory leaks may occur when an exception is thrown and caught.
-
- * My exception scheme is not properly linked in with the standard library
- exceptions. In particular, my scheme may fail to catch out-of-memory
- exceptions.
-
-
-
-
-
-
- 6 List of files
- = ==== == =====
-
-
- README readme file
- NEWMATA TXT documentation file
- NEWMATB TXT notes on the package design
- KBRIGGS TXT Keith Briggs' list of matrix libraries
-
- BOOLEAN H boolean class definition
- CONTROLW H control word definition file
- INCLUDE H details of include files and options
- MYEXCEPT H general exception handler definitions
- NEWMAT H main matrix class definition file
- NEWMATAP H applications definition file
- NEWMATIO H input/output definition file
- NEWMATNL H non-linear optimisation definition file
- NEWMATRC H row/column functions definition files
- NEWMATRM H rectangular matrix access definition files
- PRECISIO H numerical precision constants
- SOLUTION H one dimensional solve definition file
-
- BANDMAT CPP band matrix routines
- CHOLESKY CPP Cholesky decomposition
- EVALUE CPP eigenvalues and eigenvector calculation
- FFT CPP fast Fourier transform
- HHOLDER CPP QR routines
- JACOBI CPP eigenvalues by the Jacobi method
- MYEXCEPT CPP general error and exception handler
- NEWMAT1 CPP type manipulation routines
- NEWMAT2 CPP row and column manipulation functions
- NEWMAT3 CPP row and column access functions
- NEWMAT4 CPP constructors, redimension, utilities
- NEWMAT5 CPP transpose, evaluate, matrix functions
- NEWMAT6 CPP operators, element access
- NEWMAT7 CPP invert, solve, binary operations
- NEWMAT8 CPP LU decomposition, scalar functions
- NEWMAT9 CPP output routines
- NEWMATEX CPP matrix exception handler
- NEWMATNL CPP non-linear optimisation
- NEWMATRM CPP rectangular matrix access functions
- SORT CPP sorting functions
- SOLUTION CPP one dimensional solve
- SUBMAT CPP submatrix functions
- SVD CPP singular value decomposition
-
- EXAMPLE CPP example of use of package
- EXAMPLE TXT output from example
-
- GNU MAK general make file for Gnu G++
- CC MAK general make file for AT&T, Sun and HPUX
- MS_NT MAK general make file for Microsoft C 8.0 (windows NT)
- WATCOM MAK general make file for Watcom 10
- WATCO_NT MAK general make file for Watcom 10 (windows NT)
- EX_B MAK make file for example for Borland C 3.1
- EX_BC45 MAK make file for example for Borland C 4.5 (windows NT)
- TMT_B MAK make file for test for Borland C 3.1
- TMT_BC45 MAK make file for test for Borland C 4.5 (windows NT)
- TMT_Z MAK make file for test for Zortech
-
- SL_EX CPP example of OneDimSolve routine
- SL_EX TXT output from example
- NL_EX CPP example of non-linear least squares
- NL_EX TXT output from example
-
-
- See the section on testing [2.6] for details of test files.
-
-
-
- 7 Problem report form
- = ======= ====== ====
-
- Copy and paste this to your editor; fill it out and email to
- robert.davies@vuw.ac.nz
-
- or
-
- Compuserve 72777,656.
-
- Version: ............... newmat08 (19 Jan 95)
- Primary site ........... Compuserve
- Downloaded from: .......
- Your email address: ....
- Today's date: ..........
- Your machine: ..........
- Operating system: ......
- Compiler & version: ....
- Describe the problem - attach examples if possible:
-
-
-
-
-
-
-
-
-
-
-
-
-